package com.bamboo.tool.view.component.actions;

import com.bamboo.tool.config.BambooToolComponent;
import com.bamboo.tool.config.model.ProjectInfo;
import com.bamboo.tool.config.model.RestfulCloudConfig;
import com.intellij.execution.runners.ExecutionUtil;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.actionSystem.Toggleable;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class ProjectFilterAction extends ToggleAction implements DumbAware {
    private Project project;
    Runnable rebuildRunnable;
    private List<ProjectInfo> projectInfos;
    private JBPopup myFilterPopup;

    private Boolean operationMark = false;

    public ProjectFilterAction(Runnable rebuildRunnable, Project project) {
        super("项目过滤器", "项目过滤器", AllIcons.General.Filter);
        this.project = project;
        this.rebuildRunnable = rebuildRunnable;
    }

    @Override
    public boolean isSelected(@NotNull final AnActionEvent e) {
        return myFilterPopup != null && !myFilterPopup.isDisposed();
    }

    @Override
    public void setSelected(@NotNull final AnActionEvent e, final boolean state) {
        if (state) {
            showPopup(e.getRequiredData(CommonDataKeys.PROJECT), e.getInputEvent().getComponent());
        } else {
            if (myFilterPopup != null && !myFilterPopup.isDisposed()) {
                myFilterPopup.cancel();
            }
        }
    }

    private void showPopup(@NotNull Project project, @NotNull Component anchor) {
        if (myFilterPopup != null || !anchor.isValid()) {
            return;
        }
        JBPopupListener popupCloseListener = new JBPopupListener() {
            @Override
            public void onClosed(@NotNull LightweightWindowEvent event) {
                myFilterPopup = null;
            }
        };
        myFilterPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(createFilterPanel(), null).setModalContext(false).setFocusable(false).setResizable(true).setCancelOnClickOutside(false).setMinSize(new Dimension(200, 200)).setDimensionServiceKey(project, getDimensionServiceKey(), false).addListener(popupCloseListener).createPopup();
        anchor.addHierarchyListener(new HierarchyListener() {
            @Override
            public void hierarchyChanged(HierarchyEvent e) {
                if (e.getID() == HierarchyEvent.HIERARCHY_CHANGED && !anchor.isValid()) {
                    anchor.removeHierarchyListener(this);
                    if (myFilterPopup != null) {
                        myFilterPopup.cancel();
                    }
                }
            }
        });
        myFilterPopup.showUnderneathOf(anchor);
    }

    @NotNull
    @NonNls
    public String getDimensionServiceKey() {
        return "ShowFilterAction_Filter_Popup";
    }

    @Override
    public void update(@NotNull AnActionEvent e) {
        Icon icon = getTemplatePresentation().getIcon();
        e.getPresentation().setIcon(isActive() ? ExecutionUtil.getLiveIndicator(icon) : icon);
        e.getPresentation().setEnabled(isEnabled());
        Toggleable.setSelected(e.getPresentation(), isSelected(e));
    }

    protected boolean isEnabled() {
        return true;
    }

    protected boolean isActive() {
        RestfulCloudConfig cloudConfig = BambooToolComponent.getInstance(project).getState();
        ProjectInfo currentProject = cloudConfig.getCurrentProject();
        Set<Integer> selectProjects = cloudConfig.getSelectProjects();
        if (selectProjects.size() != 1) {
            return true;
        } else {
            return !selectProjects.contains(currentProject.getId());
        }
    }

    protected ElementsChooser<ProjectInfo> createChooser() {
        projectInfos = BambooToolComponent.getStoreService().getAllProjectInfos();
        RestfulCloudConfig cloudConfig = BambooToolComponent.getInstance(project).getState();
        ElementsChooser<ProjectInfo> res = new ElementsChooser<>(projectInfos, false) {
            @Override
            protected String getItemText(@NotNull ProjectInfo value) {
                return value.getProjectName();
            }

            @Nullable
            @Override
            protected Icon getItemIcon(@NotNull ProjectInfo value) {
                return AllIcons.Nodes.Project;
            }


        };
        Set<Integer> projectIds = new HashSet<>(cloudConfig.getSelectProjects());
        List<ProjectInfo> selectProjects = projectInfos.stream().filter(e -> projectIds.contains(e.getId())).collect(Collectors.toList());
        cloudConfig.getSelectProjects().clear();
        selectProjects.stream().forEach(e->cloudConfig.getSelectProjects().add(e.getId()));
        res.markElements(selectProjects);
        ElementsChooser.ElementsMarkListener<ProjectInfo> listener = (element, isMarked) -> {
            if (!operationMark) {
                if (isMarked) {
                    cloudConfig.getSelectProjects().add(element.getId());
                } else {
                    cloudConfig.getSelectProjects().remove(element.getId());
                }
                rebuildRunnable.run();
            }

        };
        res.addElementsMarkListener(listener);
        return res;
    }

    private JComponent createFilterPanel() {
        ElementsChooser<ProjectInfo> chooser = createChooser();

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.add(chooser);
        JPanel buttons = new JPanel();
        JButton all = new JButton(IdeBundle.message("big.popup.filter.button.all"));
        all.addActionListener(e -> {
            chooser.markElements(projectInfos);
        });
        buttons.add(all);
        JButton none = new JButton("默认");
        none.addActionListener(e -> {
            operationMark = Boolean.TRUE;
            RestfulCloudConfig state = BambooToolComponent.getInstance(project).getState();
            Set<Integer> selectProjects = state.getSelectProjects();
            ProjectInfo currentProject = state.getCurrentProject();
            selectProjects.clear();
            selectProjects.add(currentProject.getId());
            List<ProjectInfo> selects = projectInfos.stream().filter(a -> currentProject.getId().equals(a.getId())).collect(Collectors.toList());
            chooser.setAllElementsMarked(false);
            chooser.markElements(selects);
            rebuildRunnable.run();
            operationMark = Boolean.FALSE;
        });
        buttons.add(none);
        panel.add(buttons);
        return panel;
    }
}
